#ifndef _HELIX_PHYSICS_H_
#define _HELIX_PHYSICS_H_

#include "../../Helix.h"
#include "../../HObject.h"
#include "../../Log.h"
#include "../../Math/HelixMath.h"
#include "PhysObject.h"
#include "PhysObjRepresentation.h"

namespace helix
{
	/** This is an interface for a physics engine.
	*/
	class MY_CLASS Physics
	{
	private:
		Vector minWorldExtents;
		Vector maxWorldExtents;
	public:

		/** Create the physics simulation object.  Specify the extents of the simulated world.
		*	\param minWorldExtents Vector that represents the minimum distance in each axis 
		*	that should be included in the simulated world.  Ex <-1000.0,-1000.0,-1000.0>
		*	\param maxWorldExtents Vector that represents the maximum distance in each axis
		*	that should be included in the simulated world.  Ex <1000.0,1000.0,1000.0>
		*	
		*	\note The two parameters form a bounding box for all of the simulated objects.  Behavior
		*   outside of this box is undefined.
		*/
		Physics(Vector minWorldExtents, Vector maxWorldExtents)
		{
			this->minWorldExtents.setVector(minWorldExtents);
			this->maxWorldExtents.setVector(maxWorldExtents);
		}

		virtual ~Physics()
		{
		}

		/** Create a PhysObject from the supplied mesh.  
		*	\param rep The PhysObjRepresentation object that represents the graphics object we want
		*	to simulate.  The representation should try to match the actual object as closely as possible.
		*	\param isStatic A bool that determins whether or not the PhysObject can move.  If an object is
		*	static, it simply means that in a collision it will behave as if it has infinit mass (e.g. the 
		*   ground.  If an object is dynamic, it means that collisions will cause some change in its
		*	physical simulation.
		*	\return a new instance of a PhysObject object if it was successful, otherwise NULL
		*	\note Some operations on a static object are undefined (e.g. setting mass or velocity).  It is
		*	a best practice to set up all of your static objects before running through a simulation and then
		*	leave them alone until the simulation is over.  Only in special cases would you need to 
		*	move or modify a static object.  \see helix::PhysObject
		*/
		virtual PhysObject *createPhysObject(PhysRepresentation *rep,bool isStatic) = 0;

		/** Delete the specified PhysObject instance, freeing it from the physics simulation  
		*	\param mesh The PhysObject that we want to delete and remove from the physics simulation.
		*/
		virtual void deletePhysObject(PhysObject *physObj) = 0;

		/** Updates the physics simulation.  Performs collision detection and physically simulates
		*	all physics objects.
		*	\param dTime the time in seconds to peform the simulation for.  Practical values for this
		*	are usually less than 1/25 of a second.  Different physics engines will perform 
		*   better or worse depending on this value.
		*/
		virtual void update(double dTime) = 0;
	};

}

#endif